<?php  

/**
 * 对微信小程序用户加密数据的解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */


/**
 * error code 说明.
 * <ul>

 *    <li>-41001: encodingAesKey 非法</li>
 *    <li>-41003: aes 解密失败</li>
 *    <li>-41004: 解密后得到的buffer非法</li>
 *    <li>-41005: base64加密失败</li>
 *    <li>-41016: base64解密失败</li>
 * </ul>
 */
namespace Org\Util;

class ErrorCode
{
	public static $OK = 0;
	public static $IllegalAesKey = -41001;
	public static $IllegalIv = -41002;
	public static $IllegalBuffer = -41003;
	public static $DecodeBase64Error = -41004;
}


namespace Org\Util;

class WXyjxcx
{

    const WX_API_URL = "https://api.weixin.qq.com/sns/jscode2session";

    const WX_NOTIFY_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send";

    const WX_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";

    const WX_MSG_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check";

    const WX_ACTIVITY_ID_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create";

	/**
	 * 构造函数
	 * @param $sessionKey string 用户在小程序登录后获取的会话密钥
	 * @param $appid string 小程序的appid
	 */
	public function __construct()
	{
		//$this->sessionKey = $sessionKey;
		//$this->appid = $appid;
	}


	/**
	 * 检验数据的真实性，并且获取解密后的明文.
	 * @param $encryptedData string 加密的用户数据
	 * @param $iv string 与用户数据一同返回的初始向量
	 * @param $data string 解密后的原文
     *
	 * @return int 成功0，失败返回对应的错误码
	 */
	public function decryptData( $encryptedData, $iv, $appid, $sessionKey, &$data )
	{
		if (strlen($sessionKey) != 24) {
			return ErrorCode::$IllegalAesKey;
		}
		$aesKey=base64_decode($sessionKey);

        
		if (strlen($iv) != 24) {
			return ErrorCode::$IllegalIv;
		}
		$aesIV=base64_decode($iv);

		$aesCipher=base64_decode($encryptedData);

		$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

		$dataObj=json_decode( $result );
		if( $dataObj  == NULL )
		{
			return ErrorCode::$IllegalBuffer;
		}
		if( $dataObj->watermark->appid != $appid )
		{
			return ErrorCode::$IllegalBuffer;
		}
		$data = $result;
		return ErrorCode::$OK;
	}

    /**
     * 获取openid
     * @param $params
     *
     * @return array
     */
    public function getOpenid($params)
    {
        if (empty($params))
        {
            return array();
        }
        $url = self::WX_API_URL ."?". http_build_query($params);
        return $this->request($url);
    }

    /**
     * 获取微信AccessToken
     */
    public function getAccessToken($params)
    {
        if (empty($params))
        {
            return array();
        }
        $url = self::WX_TOKEN_URL ."?". http_build_query($params);
        return $this->request($url);
    }

    /**
     * 获取微信AccessToken
     */
    public function getCreateActivityId($params)
    {
        if (empty($params))
        {
            return array();
        }
        $url = self::WX_ACTIVITY_ID_URL ."?". http_build_query($params);
        return $this->request($url);
    }

    /**
     * 发送微信内容合法验证
     */
    public function sendCheck($params) {
        if (empty($params))
        {
            return array();
        }
        $url = self::WX_MSG_CHECK_URL. "?access_token=". $params['access_token'];
        $data['content'] = $params['content'];

        return $this->request($url,$data,'json');
    }

    /**
     * 发送微信通知
     * @param $params
     *
     * @return array
     */
    public function sendNotify($params)
    {
        if (empty($params))
        {
            return array();
        }

        $url = self::WX_NOTIFY_URL. "?access_token=". $params['access_token'];
        //unset($params['access_token']);
        return $this->request($url, $params, 'json');
    }


    /**
     * 发起http请求
     * @param string $url 访问路径
     * @param array $params 参数，该数组多于1个，表示为POST
     * @param string $type 发送类型，默认普通  还支持json $_POST=json_decode(file_get_contents('php://input'), TRUE);
     * @param int $expire 请求超时时间
     * @param array $extend 请求伪造包头参数
     * @return array    返回的为一个请求状态，一个内容
     */
    private function request($url, $params = array(), $type='', $expire = 5, $extend = array())
    {
        $_curl = curl_init();
        $_header = array(
            'Accept-Language: zh-CN',
            'Connection: Keep-Alive',
            'Cache-Control: no-cache'
        );

        if($type=='json'){
            $_header = array(
                "Content-type: application/json;charset=UTF-8",
                "Accept: application/json",
                "Cache-Control: no-cache",
                "Pragma: no-cache"
            );
            //需要在对验证内容进行json编码是处理，$data = json_encode(array('content'=>$checkContent),JSON_UNESCAPED_UNICODE);
            //JSON_UNESCAPED_UNICODE（中文不转为unicode ，对应的数字 256）
            //但是json编码是不使用JSON_UNESCAPED_UNICODE，$data其实是ASCII编码，而非utf-8,就导致验证什么内容均可通过检测
            $params = json_encode($params,JSON_UNESCAPED_UNICODE);
        }

        // 只要第二个参数传了值之后，就是POST的
        if (!empty($params) && is_array($params)) {
            curl_setopt($_curl, CURLOPT_POSTFIELDS, http_build_query($params));
            curl_setopt($_curl, CURLOPT_POST, true);
        }
        //json格式
        if (!empty($params) && is_string($params) && $type=='json') {
            curl_setopt($_curl, CURLOPT_POSTFIELDS, $params);
            curl_setopt($_curl, CURLOPT_POST, true);
        }

        curl_setopt($_curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($_curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        curl_setopt($_curl, CURLOPT_URL, $url);
        curl_setopt($_curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($_curl, CURLOPT_USERAGENT, 'API PHP CURL');
        curl_setopt($_curl, CURLOPT_HTTPHEADER, $_header);

        if ($expire > 0) {
            curl_setopt($_curl, CURLOPT_TIMEOUT, $expire); // 处理超时时间
            curl_setopt($_curl, CURLOPT_CONNECTTIMEOUT, $expire); // 建立连接超时时间
        }

        // 额外的配置
        if (!empty($extend)) {
            curl_setopt_array($_curl, $extend);
        }

        $result['result'] = curl_exec($_curl);
        $result['code'] = curl_getinfo($_curl, CURLINFO_HTTP_CODE);
        $result['info'] = curl_getinfo($_curl);
        if ($result['result'] === false) {
            $result['result'] = curl_error($_curl);
            $result['code'] = -curl_errno($_curl);
        }

        curl_close($_curl);
        return $result;
    }

}



